using Unity.Collections;
using Unity.Collections.LowLevel.Unsafe;
using Unity.Mathematics;
using IJobFor = Unity.Jobs.IJobFor;

namespace Tutorial5_PTR
{
    // 数据分类，紧密排列
    // 数据在内存中的排列： AAABBBCCCAAABBBCCCAAABBBCCC
    public struct TransformSOA
    {
        public NativeArray<float3> PosArr;
        public NativeArray<float4> RotArr;
        public NativeArray<float> ScaleArr;
    }
    
    // 数据集中，不同类型排列分散
    // 数据在内存中的排列： ABCABCABCABCABCABCABCABCABCABC
    public struct TransformAoS
    {
        public float3 position;
        public quaternion rotation;
        public float3 scale;
    }
    
    // SOA
    public struct TransformSOAJob : IJobFor
    {
        [NativeDisableContainerSafetyRestriction]
        public TransformSOA TransformSoa;
        
        [ReadOnly]public float DeltaTime;
        [ReadOnly]public float3 Velocity;
        
        public void Execute(int index)
        {
            // *************SOA 组织数据的方式：*************
            // 直接更新即可
            for (int i = 0; i < TransformSoa.PosArr.Length; i++)
            {
                TransformSoa.PosArr[i] += Velocity * DeltaTime;
            }
            // TODO : 其它...
        }
    }
    
    // AOS
    public struct TransformAOSJob : IJobFor
    {
        public NativeArray<TransformAoS> transform_AOS;
        [ReadOnly] public float3 velocity;
        [ReadOnly] public float deltaTime;

        public void Execute(int index)
        {
            unsafe
            {
                // *************AOS 组织数据的方式：*************
                // 方式一 ： 这种方式效率较低
                // var trans = transform_AOS[index]; // 一份拷贝
                // trans.position += velocity * deltaTime;
                // transform_AOS[index] = trans; // 因为是结构体，所以还回去
            
                // 方式二 ： 用指针
                var transformPtr = (TransformAoS*)transform_AOS.GetUnsafePtr();
                ref var transform = ref transformPtr[index];
                transform.position += velocity * deltaTime;
            }
        }
    }
    
}
